/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rw.ac.kiosc.jdbc.school.hibernate.dao;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import rw.ac.kiosc.jdbc.school.dao.DepartmentDAO;
import rw.ac.kiosc.jdbc.school.orm.Department;
import rw.ac.kiosc.jdbc.school.orm.Student;

/**
 *
 * @author antoine
 */
public class DepartmentHibernateDAOImpl extends DAO implements DepartmentDAO {

    public static DepartmentHibernateDAOImpl instance;

    public static DepartmentHibernateDAOImpl getInstance() {
        if (instance == null) {
            instance = new DepartmentHibernateDAOImpl();
        }
        return instance;
    }

    private DepartmentHibernateDAOImpl() {
    }

    public Department saveDepartment(Department department) {
        try {
            begin();
            int id = (Integer) getSession().save(department);
            commit();
            Department dpt = getDepartmentById(id);
            return dpt;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return null;
        }
    }

    public Department updateDepartment(Department department) {
        try {
            begin();
            getSession().update(department);
            commit();
            return department;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return null;
        }
    }

    public Department saveOrUpdateDepartment(Department department) {
        try {
            begin();
            getSession().saveOrUpdate(department);
            commit();
            return department;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return null;
        }
    }

    public boolean deleteDepartment(Department department) {
        try {
            begin();
            getSession().delete(department);
            commit();
            return true;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return false;
        }
    }

    public Department getDepartmentById(int departmentId) {
        try {
            begin();
            //Query q = getSession().createQuery("from Department where departmentId = :ref");
            //q.setInteger("ref", departmentId);
            //Department dpt = (Department) q.uniqueResult();


            Department dpt = (Department) getSession().createCriteria(Department.class).
                    add(Restrictions.idEq(departmentId)).uniqueResult();


            commit();
            return dpt;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return null;
        }
    }

    public Department getDepartmentByAcronym(String str) {
        try {
            begin();

            //Query q = getSession().createQuery("from Department where acronym = :ref");
            //q.setString("ref", acronym);
            //Department dpt = (Department) q.uniqueResult();


            Department dpt = (Department) getSession().
                    createCriteria(Department.class).
                    add(Restrictions.eq("acronym", str)).
                    uniqueResult();

            commit();
            return dpt;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return null;
        }
    }

    public List<Department> getAllDepartments() {
        try {
            begin();
            //List<Department> departments = (List<Department>) getSession().createQuery("from Department").list();

            List<Department> departments = (List<Department>) getSession().
                    createCriteria(Department.class).
                    addOrder(Order.asc("acronym")).list();
            commit();
            return departments;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return new ArrayList<Department>();
        }
    }

    public List<Department> getDepartmentsByName(String departmentName) {
        try {
            begin();
            List<Department> departments = getSession().createCriteria(Department.class).
                    add(Restrictions.like("name", departmentName)).
                    addOrder(Order.asc("acronym")).list();
            commit();
            return departments;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return new ArrayList<Department>();
        }
    }

    public List<Department> getDepartmentsByNumberOfYears(int noy) {
        try {
            begin();
            //Query q = getSession().createQuery("from Department where numberOfYears= :ref");
            //q.setInteger("ref", noy);
            // List<Department> departments = (List<Department>) q.list();

            List<Department> departments = getSession().
                    createCriteria(Department.class).
                    add(Restrictions.eq("numberOfYears", noy)).
                    addOrder(Order.asc("acronym")).
                    list();

            commit();
            return departments;
        } catch (Exception ex) {
            System.out.println(ex.toString());
            ex.printStackTrace();
            rollback();
            return new ArrayList<Department>();
        }
    }

    public Department getDepartmentByStudent(Student student) {
        return student.getDepartment();
    }
}
